using Microsoft.Extensions.Logging;
using SeataNet.Core.Configuration;
using System.Collections.Concurrent;
using System.Net.Http;

namespace SeataNet.Core.RPC
{
    /// <summary>
    /// RPC客户端管理器接口
    /// </summary>
    public interface IRpcClientManager
    {
        /// <summary>
        /// 获取RPC客户端
        /// </summary>
        /// <param name="serviceName">服务名称</param>
        /// <returns>RPC客户端</returns>
        Task<IRpcClient> GetRpcClientAsync(string serviceName);
    }

    /// <summary>
    /// 默认RPC客户端管理器
    /// </summary>
    public class DefaultRpcClientManager : IRpcClientManager
    {
        private readonly ILogger<DefaultRpcClientManager> _logger;
        private readonly ILoggerFactory _loggerFactory;
        private readonly HttpClient _httpClient;
        private readonly SeataConfiguration _configuration;
        private readonly ConcurrentDictionary<string, IRpcClient> _clients;

        public DefaultRpcClientManager(
            ILogger<DefaultRpcClientManager> logger,
            ILoggerFactory loggerFactory,
            HttpClient httpClient,
            SeataConfiguration configuration)
        {
            _logger = logger;
            _loggerFactory = loggerFactory;
            _httpClient = httpClient;
            _configuration = configuration;
            _clients = new ConcurrentDictionary<string, IRpcClient>();
        }

        public async Task<IRpcClient> GetRpcClientAsync(string serviceName)
        {
            if (_clients.TryGetValue(serviceName, out var existingClient))
            {
                return existingClient;
            }

            try
            {
                _logger.LogDebug($"创建RPC客户端: ServiceName={serviceName}");

                var clientLogger = _loggerFactory.CreateLogger<DefaultRpcClient>();
                var client = new DefaultRpcClient(clientLogger, _httpClient);
                
                // 初始化客户端
                var serverAddress = _configuration.Transport.ServerAddress;
                var applicationId = _configuration.ApplicationId;
                var transactionServiceGroup = _configuration.TransactionServiceGroup;

                var initialized = await client.InitializeAsync(serverAddress, applicationId, transactionServiceGroup);
                if (!initialized)
                {
                    _logger.LogError($"RPC客户端初始化失败: ServiceName={serviceName}");
                    return null;
                }

                _clients.TryAdd(serviceName, client);
                _logger.LogDebug($"RPC客户端已创建: ServiceName={serviceName}");

                return client;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"获取RPC客户端失败: ServiceName={serviceName}");
                return null;
            }
        }
    }
}